﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.IO;
using System.Resources;
using System.Globalization;
using System.Threading;

namespace Vit.Common.Providers.Localization
{
    public class ResourceManagerLocalizationProvider : ILocalizationProvider
    {
        internal class AssemblyNameResourceManager
        {
            public string AssemblyName { get; set; }
            public ResourceManager ResourceManager { get; set; }
        }

        private List<AssemblyNameResourceManager> resourceManagers = new List<AssemblyNameResourceManager>();

        private string NormalizeAssemblyName(string assemblyName)
        {
            return assemblyName.Replace(".", "_");
        }

        private ResourceManager GetResourceManager(string assemblyName)
        {
            assemblyName = NormalizeAssemblyName(assemblyName);
            var nrm = resourceManagers.FirstOrDefault(o => string.Equals(o.AssemblyName, assemblyName, StringComparison.InvariantCultureIgnoreCase));
            if (nrm != null)
                return nrm.ResourceManager;

            //ResourceManager rm = ResourceManager.CreateFileBasedResourceManager(assemblyName, AppDomain.CurrentDomain.BaseDirectory, null);
            //if (rm != null)
            //{
            //    AddResourceManager(assemblyName, rm);
            //}

            //return rm;

            return null;
        }

        public void AddResourceManager(string assemblyName, ResourceManager rm)
        {
            assemblyName = NormalizeAssemblyName(assemblyName);
            if (resourceManagers.Any(o => string.Equals(o.AssemblyName, assemblyName, StringComparison.InvariantCultureIgnoreCase)))
                resourceManagers.RemoveAll(o => string.Equals(o.AssemblyName, assemblyName, StringComparison.InvariantCultureIgnoreCase));
            rm.IgnoreCase = true;
            resourceManagers.Add(new AssemblyNameResourceManager() { AssemblyName = assemblyName, ResourceManager = rm });
        }

        #region ILocalizationService Members

        public void Initialize()
        {
        }

        public void ReleaseAllResources()
        {
            resourceManagers.ForEach(o => o.ResourceManager.ReleaseAllResources());
            resourceManagers.Clear();
        }

        public string GetString(string assemblyName, string resourceName)
        {
            return GetString(assemblyName, resourceName, Thread.CurrentThread.CurrentCulture.Name);
        }

        public string GetString<T>(string resourceName)
        {
            return GetString<T>(resourceName, Thread.CurrentThread.CurrentCulture.Name);
        }

        public string GetString(object obj, string resourceName)
        {
            return GetString(obj, resourceName, Thread.CurrentThread.CurrentCulture.Name);
        }

        public string GetString(Type type, string resourceName)
        {
            return GetString(type, resourceName, Thread.CurrentThread.CurrentCulture.Name);
        }

        public string GetString(string assemblyName, string resourceName, string cultureInfo)
        {
            if (assemblyName == "mscorlib")
                return null;
            if (string.IsNullOrWhiteSpace(cultureInfo))
                cultureInfo = "zh-CN";
            assemblyName = NormalizeAssemblyName(assemblyName);
            var nrm = GetResourceManager(assemblyName);
            if (nrm != null)
                return nrm.GetString(resourceName, new CultureInfo(cultureInfo));
            object resVal = null;
            try
            {
                resVal = HttpContext.GetGlobalResourceObject(assemblyName, resourceName, new CultureInfo(cultureInfo));

            }
            catch { }
            return resVal == null ? resourceName : resVal.ToString();
        }

        public string GetString<T>(string resourceName, string cultureInfo)
        {
            return GetString(typeof(T), resourceName, cultureInfo);
        }

        public string GetString(object obj, string resourceName, string cultureInfo)
        {
            return GetString(obj.GetType(), resourceName, cultureInfo);
        }

        public string GetString(Type type, string resourceName, string cultureInfo)
        {
            return GetString(type.Namespace, resourceName, cultureInfo);
        }

        public void SetString(string assemblyName, string resourceName, string cultureInfo, string value)
        {
        }

        public void Save()
        {
        }

        public bool SupportRuntimeResourceManagement
        {
            get { return false; }
        }

        #endregion

        #region IProvider Members

        public string Name
        {
            get { return "ResourceManagerLocalizationProvider"; }
        }

        #endregion
    }
}
